package org.onionframework.persistence.dao.expression;

import org.hibernate.Criteria;
import org.hibernate.EntityMode;
import org.hibernate.HibernateException;
import org.hibernate.criterion.CriteriaQuery;
import org.hibernate.criterion.SimpleExpression;
import org.hibernate.engine.spi.TypedValue;
import org.hibernate.type.StandardBasicTypes;
import org.onionframework.persistence.dao.projection.DateStringUtils;

public class DateStringExpression extends SimpleExpression {

	private static final long serialVersionUID = -6340741787537565173L;
	private String propertyName;
	private Object value;
	private DateStringUtils dateStringUtils;
	
	protected DateStringExpression(String propertyName, Object value, String op, String pattern) {
		super(propertyName, value, op);
		this.propertyName = propertyName;
		this.value = value;
		this.dateStringUtils = new DateStringUtils(pattern);
	}

	public String toSqlString(Criteria criteria, CriteriaQuery criteriaQuery)
	throws HibernateException {

		String[] columns = criteriaQuery.getColumnsUsingProjection(criteria, propertyName);
		//Type type = criteriaQuery.getTypeUsingProjection(criteria, propertyName);
		StringBuffer fragment = new StringBuffer();
		if (columns.length>1) fragment.append('(');
		//SessionFactoryImplementor factory = criteriaQuery.getFactory();
		for ( int i=0; i<columns.length; i++ ) {
			fragment.append( this.dateStringUtils.toSql(columns[i]) );
			fragment.append(' ').append( getOp() ).append(' ').append("?");
			if ( i<columns.length-1 ) fragment.append(" and ");
		}
		if (columns.length>1) fragment.append(')');
		return fragment.toString();

	}

	public TypedValue[] getTypedValues(Criteria criteria, CriteriaQuery criteriaQuery)
	throws HibernateException {
		if("=".equals(this.getOp()))
			return new TypedValue[]{new TypedValue(StandardBasicTypes.STRING,this.value,EntityMode.POJO)};
		else
			return new TypedValue[]{new TypedValue(StandardBasicTypes.STRING,"%" + this.value + "%",EntityMode.POJO)};
	}

}
